package negocio;

import datos.Programa;
import java.net.URL;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
import javax.persistence.PersistenceContext;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

/**
 *
 * @author Ing. Monica Merlo, Ing. Agustin  Fernandez
 */
@Stateless
public class GestorProgramaBean implements GestorProgramaRemote, GestorProgramaLocal {
    static Logger logger = Logger.getLogger(GestorProgramaBean.class);
    public static void log4j(Exception e){
        URL url = GestorProgramaBean.class.getResource("/configuracion/log4j.properties");
        PropertyConfigurator.configure(url);
        logger.error(e);
    }

    @PersistenceContext
    private EntityManager em;

    /***
     *
     * @param object
     */
    public void persist(Object object) {
        em.persist(object);
    }

    /***
     * Retorna una lista con todos los objetos
     * de tipo Programa, en caso contrario retorna Null.
     * @return listado de todos los programas de construcción de obra
     * almacenados en la Base de Datos, ordenados por nombre
     * Interfaz remota
     */
    public List consultarProgramaRemote() {
        try {
            javax.persistence.Query q = em.createNamedQuery("Programa.encontrarTodos");
            return q.getResultList();

        } catch (Exception e) {
            GestorProgramaBean.log4j(e);
            return null;
        }
    }

    /***
     * Retorna una lista con todas las instancias de tipo Programa, en
     * caso contrario retorna Null.
     * @return listado de todos los programas de construcción de obra
     * almacenados en la Base de Datos, ordenados por nombre
     * Interfaz local
     */
    public List consultarPrograma() {
        try {
            javax.persistence.Query q = em.createNamedQuery("Programa.encontrarTodos");
            return q.getResultList();

        } catch (Exception e) {
            GestorProgramaBean.log4j(e);
            return null;
        }
    }

    /***
     * Retorna un objeto de tipo Programa cuyo nombre cuyo nombre
     * coincide con el parametro nombre, en caso contrario retorna Null.
     * @param nombre
     * @return un programa en particular definido, su nombre, previamente en la UI
     * Interfaz local
     */
    public Programa encontrarPrograma(String nombre) {
        try {
            javax.persistence.Query q = em.createNamedQuery("Programa.findByNombre");
            q.setParameter("nombre", nombre);
            return (Programa) q.getSingleResult();

        } catch (Exception e) {
            GestorProgramaBean.log4j(e);
            return null;
        }

    }

    /***
     * Retorna un objeto de tipo Programa cuyo nombre cuyo nombre
     * coincide con el parametro nombre, en caso contrario retorna Null.
     * @param nombre
     * @return un programa en particular definido, su nombre, previamente en la UI
     * Interfaz remota
     */
    public Programa encontrarProgramaRemote(String nombre) {
        try {
            javax.persistence.Query q = em.createNamedQuery("Programa.findByNombre");
            q.setParameter("nombre", nombre);
            return (Programa) q.getSingleResult();

        } catch (Exception e) {
            GestorProgramaBean.log4j(e);
            return null;
        }

    }

    /***
     * Crea una nueva instancia de tipo Programa, reornando True en caso de exito
     * y False en caso contrario.
     * @param programa
     * @return true en el caso de que la nueva instancia de la clase Programa haya sido almacenada con éxito,
     * false en caso de que la nueva instancia de la clase Programa no haya sido almacenada con éxito,
     * Interfaz remota
     */
    public boolean agregarProgramaRemote(Programa programa) {
        try {
            persist(programa);
            return true;
        } catch (Exception e) {
            GestorProgramaBean.log4j(e);
            return false;
        }

    }

    /***
     * Crea una nueva instancia de tipo Programa, reornando True en caso de exito
     * y False en caso contrario.
     * @param programa
     * @return true en el caso de que la nueva instancia de la clase Programa haya sido almacenada con éxito,
     * false en caso de que la nueva instancia de la clase Programa no haya sido almacenada con éxito,
     * Interfaz local
     */
    public boolean agregarPrograma(Programa programa) {

        try {
            persist(programa);
            return true;
        } catch (Exception e) {
            GestorProgramaBean.log4j(e);
            return false;
        }

    }

    /***
     * Busca la instancia de tipo Programa que se desea actualizar, y una
     * vez encontrada se actualizan sus atributos, retornando True en caso de
     * exito y False en caso contrario.
     * @param programa
     * @return true en el caso de que la instancia de la clase Programa haya sido modificada
     * y almacenada con éxito, previamente encontrada a través de su ID. False en caso contrario.
     * Interfaz remota
     */
    public boolean modificarProgramaRemote(Programa programa) {
        try {
            Programa pro = em.find(Programa.class, programa.getId());
            pro.setDescripcion(programa.getDescripcion().toUpperCase());
            pro.setNombre(programa.getNombre().toUpperCase());
            pro.setFechaInicio(programa.getFechaInicio());
            pro.setFechaFin(programa.getFechaFin());
            persist(pro);
            return true;
        } catch (Exception e) {
            GestorProgramaBean.log4j(e);
            return false;
        }
    }

    /***
     * Busca la instancia de tipo Programa que se desea actualizar, y una
     * vez encontrada se actualizan sus atributos, retornando True en caso de
     * exito y False en caso contrario.
     * @param programa
     * @return true en el caso de que la instancia de la clase Programa haya sido modificada
     * y almacenada con éxito, previamente encontrada a través de su ID. False en caso contrario.
     * Interfaz local
     */
    public boolean modificarPrograma(Programa programa) {
        try {
            Programa pro = em.find(Programa.class, programa.getId());
            pro.setDescripcion(programa.getDescripcion().toUpperCase());
            pro.setNombre(programa.getNombre().toUpperCase());
            pro.setFechaInicio(programa.getFechaInicio());
            pro.setFechaFin(programa.getFechaFin());
            persist(pro);
            return true;
        } catch (Exception e) {
            GestorProgramaBean.log4j(e);
            return false;
        }
    }

    /***
     * Elimina una instancia de tipo Programa, retornando True en caso de exito
     * y False en caso contrario.
     * @param programa
     * @return true en caso de encontrar el objeto de tipo Programa a través de su ID,
     * y removerlo de forma física de la Base de Datos. False en caso contrario.
     * Interfaz remota
     */
    public boolean eliminarProgramaRemote(Programa programa) {
        try {
            Programa pro = em.find(Programa.class, programa.getId());
            em.remove(pro);
            return true;
        } catch (Exception e) {
            GestorProgramaBean.log4j(e);
            return false;
        }
    }

    /***
     * Elimina una instancia de tipo Programa, retornando True en caso de exito
     * y False en caso contrario.
     * @param programa
     * @return true en caso de encontrar el objeto de tipo Programa a través de su ID,
     * y removerlo de forma física de la Base de Datos. False en caso contrario.
     * Interfaz local
     */
    public boolean eliminarPrograma(Programa programa) {
        try {
            Programa pro = em.find(Programa.class, programa.getId());
            em.remove(pro);
            return true;
        } catch (Exception e) {
            GestorProgramaBean.log4j(e);
            return false;
        }
    }

    /***
     * Valida que no existan dos instancias de tipo Programa con el mismo nombre.
     * @param programa
     * @return true en caso de que el objeto haya sido encontrado por su nombre y false en caso contrario
     * Interfaz local
     */
    public boolean existeNombrePrograma(Programa programa) {
        try {
            javax.persistence.Query q = em.createNamedQuery("Programa.buscarPorNombre");
            q.setParameter("nombre", programa.getNombre().toUpperCase());
            if (q.getSingleResult() != null) {
                return true;
            } else {
                return false;
            }
        } catch (NoResultException ne) {
            GestorProgramaBean.log4j(ne);
            return false;
        } catch (NonUniqueResultException nue) {
            GestorProgramaBean.log4j(nue);
            return true;
        } catch (IllegalStateException ie) {
            GestorProgramaBean.log4j(ie);
            return true;
        }

    }

    /***
     * Valida que no existan dos instancias de tipo Programa con el mismo nombre.
     * Retornando True en caso de exito y False en caso contrario.
     * @param programa
     * @return true en caso de que el objeto haya sido encontrado por su nombre y false en caso contrario
     * Interfaz remota
     */
    public boolean existeNombreProgramaRemote(Programa programa) {
        try {
            javax.persistence.Query q = em.createNamedQuery("Programa.buscarPorNombre");
            q.setParameter("nombre", programa.getNombre().toUpperCase());
            if (q.getSingleResult() != null) {
                return true;
            } else {
                return false;
            }
        } catch (NoResultException ne) {
            GestorProgramaBean.log4j(ne);
            return false;
        } catch (NonUniqueResultException nue) {
            GestorProgramaBean.log4j(nue);
            return true;
        } catch (IllegalStateException ie) {
            GestorProgramaBean.log4j(ie);
            return true;
        }

    }

    /***
     * Valida que no existan dos instancias de tipo Programa con el mismo nombre.
     * Retornando True en caso de exito y False en caso contrario.
     * @param programa
     * @return true en caso de que el objeto haya sido encontrado en la Base de datos por su ID y nombre
     * Interfaz local
     */
    public boolean existeNombreProgramaModificar(Programa programa) {
        try {
            javax.persistence.Query q = em.createNamedQuery("Programa.findByNombreModificar");
            q.setParameter("nombre", programa.getNombre().toUpperCase());
            q.setParameter("id", programa.getId());
            if (q.getSingleResult() != null) {
                return true;
            } else {
                return false;
            }
        } catch (NoResultException ne) {
            GestorProgramaBean.log4j(ne);
            return false;
        } catch (NonUniqueResultException nue) {
            GestorProgramaBean.log4j(nue);
            return true;
        } catch (IllegalStateException ie) {
            GestorProgramaBean.log4j(ie);
            return true;
        }
    }

    /***
     * Valida que no existan dos instancias de tipo Programa con el mismo nombre.
     * Retornando True en caso de exito y False en caso contrario.
     * @param programa
     * @return true en caso de que el objeto haya sido encontrado en la Base de datos por su ID y nombre
     * Interfaz remota
     */
    public boolean existeNombreProgramaModificarRemote(Programa programa) {
        try {
            javax.persistence.Query q = em.createNamedQuery("Programa.findByNombreModificar");
            q.setParameter("nombre", programa.getNombre().toUpperCase());
            q.setParameter("id", programa.getId());
            if (q.getSingleResult() != null) {
                return true;
            } else {
                return false;
            }
        } catch (NoResultException ne) {
            GestorProgramaBean.log4j(ne);
            return false;
        } catch (NonUniqueResultException nue) {
            GestorProgramaBean.log4j(nue);
            return true;
        } catch (IllegalStateException ie) {
            GestorProgramaBean.log4j(ie);
            return true;
        }
    }

    /***
     * Retorna una lista con todos los nombres de las instancias de Programa,
     * en caso contrario retorna Null.
     * @return una lista de todos los nombres de los programas ordenados, null en caso contrario
     * Interfaz local
     */
    public List programas() {
        try {
            javax.persistence.Query q = em.createNamedQuery("Programa.encontrarTodosNombre");
            return q.getResultList();

        } catch (Exception e) {
            GestorProgramaBean.log4j(e);
            return null;
        }
    }

    /***
     * Retorna una lista con todos los nombres de las instancias de Programa,
     * en caso contrario retorna Null.
     * @return una lista de todos los nombres de los programas ordenados, null en caso contrario
     * Interfaz remota
     */
    public List programasRemote() {
        try {
            javax.persistence.Query q = em.createNamedQuery("Programa.encontrarTodosNombre");
            return q.getResultList();

        } catch (Exception e) {
            GestorProgramaBean.log4j(e);
            return null;
        }
    }

    /***
     * Valida si alguna instancia de Obra tiene asignado algun programa, retorna True
     * en caso de exito y False en caso contrario.
     * @param idPrograma
     * @return true en caso de que alguna obra tenga asignado el programa, y false en caso contrario.
     * Interfaz local
     */

    public boolean programaFueAsignadoObras(int idPrograma) {
        try {
            javax.persistence.Query q = em.createNamedQuery("Obra.programaTieneObras");
            q.setParameter("idPrograma", idPrograma);
            if (q.getResultList() != null) {
                if (q.getResultList().size() > 0) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }

        } catch (Exception e) {
            GestorProgramaBean.log4j(e);
            return false;
        }
    }

    /***
     * Valida si alguna instancia de Obra tiene asignado algun programa, retorna True
     * en caso de exito y False en caso contrario.
     * @param idPrograma
     * @return true en caso de que alguna obra tenga asignado el programa, y false en caso contrario.
     * Interfaz remota
     */
    public boolean programaFueAsignadoObrasRemote(int idPrograma) {
        try {
            javax.persistence.Query q = em.createNamedQuery("Obra.programaTieneObras");
            q.setParameter("idPrograma", idPrograma);
            if (q.getResultList() != null) {
                if (q.getResultList().size() > 0) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }

        } catch (Exception e) {
            GestorProgramaBean.log4j(e);
            return false;
        }
    }
    
}
